package com.panopset.sf;

import static com.panopset.Util.dump;
import static com.panopset.Util.x;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import com.panopset.centralen.SysInfo;

/**
 * Standard application window menu bar.
 *
 * @author Karl Dinwiddie
 *
 */
public final class AppMenuBar {

    /**
     * Frame.
     */
    private final Windoc w;

    /**
     * @param windoc
     *            Windoc
     */
    public AppMenuBar(final Windoc windoc) {
        w = windoc;
    }

    /**
     * Menu bar.
     */
    private JMenuBar mb;

    /**
     * @return Menu bar.
     */
    public JMenuBar getMenuBar() {
        if (mb == null) {
            mb = new MessageMenuBar();
            mb.add(createFileMenu());
            mb.add(createFontMenu());
            mb.add(createDataMenu());
            mb.add(createHelpMenu());
        }
        return mb;
    }

    /**
     * Override to add menus in between the File and Help menus.
     *
     * @param menuBar
     *            Menu bar.
     */
    protected void addMiddleMenus(final JMenuBar menuBar) {
        // Nothing to do for default behavior.
    }

    /**
     * Show about box.
     */
    public synchronized void doAbout() {
        w.getApp().getAboutBox().setParent(w.getApp().getTopDoc().getFrame());
        w.getApp().getAboutBox().show();
    }

    /**
     * Do system info.
     */
    public synchronized void doSystemInfo() {

        JPanel gui = new JPanel(new BorderLayout());
        JTextArea ta = new JTextArea(dump(SysInfo.getMap()));
        ta.setEditable(false);
        gui.add(BorderLayout.CENTER, new JScrollPane(ta));
        try {
            gui.add(BorderLayout.NORTH, new JLabel("Loaded from "
                    + com.panopset.Util.getSourceName(getClass())));
        } catch (Exception e) {
            ta.setText(com.panopset.Util.getStackTrace(e));
        }

        new TypicalDialog.Builder(w.getApp(), x("System Information"))
                .centerPanel(gui).construct().display();
    }

    /**
     * Do Java Properties.
     */
    public synchronized void doEnvInfo() {
        TypicalDialog.dspdlg(w.getApp(), "System Environment Variables",
                dump(System.getenv()));
    }

    /**
     * Do Java Properties.
     */
    public synchronized void doJavaProperties() {
        TypicalDialog.dspdlg(w.getApp(), "Java System Properties",
                dump(System.getProperties()));
    }

    /**
     * Do show log.
     */
    public synchronized void doShowLog() {
        TypicalDialog.dspdlg(w.getApp(), "Log", com.panopset.Util.getLog());
    }

    /**
     * @return help menu.
     */
    private JMenu createHelpMenu() {
        JMenu menu = new JMenu("Help");
        menu.setMnemonic(KeyEvent.VK_H);
        ComponentFactory.FM.register(menu, FontManager.FontType.plainArial);

        JMenuItem mi = new JMenuItem(x("About") + " "
                + w.getApp().getApplicationName());
        mi.setMnemonic(KeyEvent.VK_A);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                doAbout();
            }
        });
        ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem(x("Java Properties"));
        mi.setMnemonic(KeyEvent.VK_J);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                doJavaProperties();
            }
        });
        ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem(x("System Information"));
        mi.setMnemonic(KeyEvent.VK_J);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                doSystemInfo();
            }
        });
        ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem(x("Environment Variables"));
        mi.setMnemonic(KeyEvent.VK_E);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                doEnvInfo();
            }
        });
        ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem(x("Log"));
        mi.setMnemonic(KeyEvent.VK_J);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                doShowLog();
            }
        });
        ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
        menu.add(mi);

        return menu;
    }

    /**
     * @return file menu.
     */
    private JMenu createFontMenu() {
        JMenu menu = new JMenu("Font");
        for (final FontManager.Size size : FontManager.Size.values()) {
            JMenuItem mi = size.getMenuItem();
            mi.addActionListener(new ActionListener() {
                public void actionPerformed(final ActionEvent e) {
                    ComponentFactory.FM.setSize(size);
                }
            });
            ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
            menu.add(mi);
        }
        ComponentFactory.FM.register(menu, FontManager.FontType.plainArial);
        return menu;
    }

    /**
     * @return file menu.
     */
    private JMenu createDataMenu() {
        JMenu menu = new JMenu("Data");

        JMenuItem mi = new JMenuItem(x("Reset"));
        mi.setMnemonic(KeyEvent.VK_N);
        mi.setToolTipText(x("Reset data to defaults."));
        mi.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                // H2Util.reset();
            }
        });
        ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem(x("Debug H2"));
        mi.setMnemonic(KeyEvent.VK_N);
        mi.setToolTipText(x("Launch the H2 server to analyze data."));
        mi.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                w.getApp().getAppProps().getDataProps().getStore().startServer();
                // H2Util.startServer();
            }
        });
        ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem(x("info"));
        mi.setMnemonic(KeyEvent.VK_N);
        mi.setToolTipText(x("Show database information."));
        mi.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                // TypicalDialog.dspdlg("H2 Database Information",
                // H2Util.showInfo());
            }
        });
        ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
        menu.add(mi);

        ComponentFactory.FM.register(menu, FontManager.FontType.plainArial);
        return menu;
    }

    /**
     * @return file menu.
     */
    private JMenu createFileMenu() {
        JMenu menu = new JMenu("File");
        menu.setMnemonic(KeyEvent.VK_F);
        ComponentFactory.FM.register(menu, FontManager.FontType.plainArial);
        JMenuItem mi = null;
        if (w.getApp().hasDocuments()) {
            mi = new JMenuItem("New");
            mi.setMnemonic(KeyEvent.VK_N);
            mi.addActionListener(new ActionListener() {

                public void actionPerformed(final ActionEvent e) {
                    w.doNew();
                }
            });
            ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
            menu.add(mi);

            mi = new JMenuItem("Open");
            mi.setMnemonic(KeyEvent.VK_O);
            mi.addActionListener(new ActionListener() {

                public void actionPerformed(final ActionEvent e) {
                    w.doOpen();
                }
            });
            ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
            menu.add(mi);

            mi = new JMenuItem("Save");
            mi.setMnemonic(KeyEvent.VK_S);
            mi.addActionListener(new ActionListener() {

                public void actionPerformed(final ActionEvent e) {
                    w.doSave();
                }
            });
            ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
            menu.add(mi);

            mi = new JMenuItem("Save as");
            mi.setMnemonic(KeyEvent.VK_A);
            mi.addActionListener(new ActionListener() {

                public void actionPerformed(final ActionEvent e) {
                    w.doSaveAs();
                }
            });
            ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
            menu.add(mi);
        }

        mi = new JMenuItem("Reset");
        mi.setToolTipText(

        x("Reset all fields to defaults, set window to default size."));
        mi.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                w.getFrame().setSize(w.getApp().getDefaultSize());
            }
        });
        ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem("Quit");
        mi.setMnemonic(KeyEvent.VK_Q);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                w.getApp().shutdown();
            }
        });
        ComponentFactory.FM.register(mi, FontManager.FontType.plainArial);
        menu.add(mi);

        return menu;
    }

}
